package cn.bone.auth.security.base.filter;

import cn.bone.auth.security.base.component.RSAKeyProperties;
import cn.bone.auth.security.base.utils.JWTUtil;
import cn.bone.auth.security.bean.SysUser;
import cn.bone.auth.security.service.impl.UserDetailsServiceImpl;
import com.alibaba.fastjson.JSONObject;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Date;

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;

    private RSAKeyProperties prop;

    public TokenLoginFilter(AuthenticationManager authenticationManager, RSAKeyProperties prop){
        this.authenticationManager = authenticationManager;
        this.prop = prop;
    }

    /*接受并且解析用户凭证*/
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        try {
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,password);
            Authentication authenticate = authenticationManager.authenticate(token);
            return authenticate;
        }catch (Exception e){
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("UTF-8");
            JSONObject object = new JSONObject();
            object.put("code",101);
            object.put("message","登录失败");

            try {
                PrintWriter writer = response.getWriter();
                writer.write(object.toJSONString());
                writer.flush();
                writer.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            throw new RuntimeException("TokenLoginFilter中出现了认证异常了");
        }
    }


    /*
        用户登录成功，生成token，并且返回json数据给前端

    */
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {


        SysUser sysUser = (SysUser)(authResult.getPrincipal());


        String username = authResult.getName();
        Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();
        StringBuilder stringBuilder = new StringBuilder();
        for(GrantedAuthority grantedAuthority : authorities){
            stringBuilder.append(",");
            stringBuilder.append(grantedAuthority.getAuthority());
        }
        String tags = stringBuilder.toString();
        if(tags.length()>0){
            tags = tags.substring(1);
        }

//        SysUser sysUser = UserDetailsServiceImpl.userThreadLocal.get();

        JWTUtil.JJWTPayload payload = new JWTUtil.JJWTPayload();
        payload.setUserId(sysUser.getId());
        payload.setUsername(username);
        payload.setUserType("student");
        payload.setLoginTime(new Date().getTime());
        payload.setOrigin("web");
        payload.setTags(tags);
        String token = JWTUtil.createToken(payload, prop.getPrivateKey());

        JSONObject obj = new JSONObject();
        obj.put("code", 0);
        obj.put("token", token);
        obj.put("message", "成功");
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(obj.toJSONString());
        writer.flush();
        writer.close();
    }
}
